package com.imis.module.system.bus;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.imis.base.constant.CommonConstant;
import com.imis.base.constant.enums.SysTipEnum;
import com.imis.base.globle.Result;
import com.imis.base.util.ConvertUtils;
import com.imis.module.base.BaseBus;
import com.imis.module.system.model.converter.SysMenuConverter;
import com.imis.module.system.model.po.SysMenu;
import com.imis.module.system.model.po.SysRole;
import com.imis.module.system.model.ro.PagingQueryMenuDTO;
import com.imis.module.system.model.ro.QueryMenuDTO;
import com.imis.module.system.model.ro.SysMenuAddRO;
import com.imis.module.system.model.ro.SysMenuUpdateRO;
import com.imis.module.system.model.vo.SysMenuTreeVO;
import com.imis.module.system.model.vo.SysMenuVO;
import com.imis.module.system.service.ISysMenuService;
import com.imis.module.system.service.ISysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 功能菜单表 业务处理类
 * </p>
 *
 * @author XinLau
 * @since 2020-03-17
 */
@Service
public class SysMenuBus extends BaseBus {

    /**
     * 功能菜单表 服务类
     */
    private ISysMenuService serviceBySysMenuService;

    @Autowired
    public void setServiceBySysMenuService(ISysMenuService serviceBySysMenuService) {
        this.serviceBySysMenuService = serviceBySysMenuService;
    }

    /**
     * 系统角色表 服务类
     */
    private ISysRoleService sysRoleService;

    @Autowired
    public void setSysRoleService(ISysRoleService sysRoleService) {
        this.sysRoleService = sysRoleService;
    }

    /**
     * 添加功能菜单重复校验
     *
     * @param sysMenu - 功能菜单
     * @return Result
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/9 9:47
     */
    private Result menuAddVerification(SysMenu sysMenu) {
        if (sysMenu != null) {
//            1.根据功能菜单信息查询，该功能菜单被删除
            if (sysMenu.getDelFlag().equals(CommonConstant.DEL_FLAG_DELETE)) {
                return Result.errorsFormat(SysTipEnum.MENU_ADD_ERR_DELETE, sysMenu.getName());
            }
//            2.根据功能菜单信息查询，该功能菜单名存在
            return Result.errorsFormat(SysTipEnum.MENU_ADD_ERR_REPEAT, sysMenu.getName());
        }
        return Result.ok();
    }

    /**
     * 添加功能菜单父级功能菜单校验
     *
     * @param sysMenuParent - 父级功能菜单
     * @return Result
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/9 9:47
     */
    private Result menuAddVerificationForParent(SysMenu sysMenuParent) {
        Result result = new Result<>();
        if (sysMenuParent != null) {
//            1.根据父级功能菜单信息查询，该父级功能菜单被删除
            if (sysMenuParent.getDelFlag().equals(CommonConstant.DEL_FLAG_DELETE)) {
                return result.errorFormat(SysTipEnum.MENU_ADD_ERR_PARENT_DELETE, sysMenuParent.getName());
            }
            return result;
        }
//        2.根据父级功能菜单信息查询，该父级功能菜单不存在
        return result.errorFormat(SysTipEnum.MENU_ADD_ERR_PARENT_NON);
    }

    /**
     * 删除功能菜单校验
     *
     * @param sysMenu - 功能菜单对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    private Result menuDeleteVerification(SysMenu sysMenu) {
        Result result = new Result<>();
        if (ConvertUtils.isEmpty(sysMenu)) {
//            1.根据功能菜单信息查询，该功能菜单不存在
            return result.errorFormat(SysTipEnum.MENU_DELETE_ERR_NON);
        }
//        判断功能菜单是否分配给角色
        Long[] sysRoleIdArray = serviceBySysMenuService.selectSysRoleIdArrayByMenuId(sysMenu.getId());
        if (sysRoleIdArray.length > 0) {
//            2.根据功能菜单信息查询，该功能菜单已分配给角色使用
            return result.errorFormat(SysTipEnum.MENU_DELETE_ERR_ASSIGNED, sysMenu.getName(), Arrays.toString(sysRoleIdArray));
        }
//        判断功能菜单旗下是否存在子级功能菜单
        List<SysMenuVO> sysMenuChildList = serviceBySysMenuService.selectSysMenuListByParentId(sysMenu.getId());
        if (sysMenuChildList.size() != 0) {
//            3.根据功能菜单信息查询，该功能菜单旗下存在子级功能菜单
            return result.errorFormat(SysTipEnum.MENU_DELETE_ERR_HAVE_CHILD, sysMenu.getName());
        }
        result.setResult(SysMenuConverter.INSTANCE.domain2vo(sysMenu));
        return result;
    }

    /**
     * 功能菜单更新校验
     *
     * @param sysMenu - 功能菜单更新对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    private Result menuUpdateVerification(SysMenu sysMenu) {
        Result result = new Result<>();
        if (ConvertUtils.isEmpty(sysMenu)) {
//            1.根据功能菜单信息查询，该功能菜单不存在
            return result.errorFormat(SysTipEnum.MENU_UPDATE_ERR_NON, sysMenu.getName());
        }
        result.setResult(SysMenuConverter.INSTANCE.domain2vo(sysMenu));
        return result;
    }

    /**
     * 分页查询功能菜单
     *
     * @param pagingQueryMenuDTO - 功能菜单查询对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public Result pagingQuerySysMenuParentListByParameter(PagingQueryMenuDTO pagingQueryMenuDTO) {
        try {
            Page<SysMenuTreeVO> sysMenuParentListByParameter = serviceBySysMenuService.pagingQuerySysMenuParentListByParameter(pagingQueryMenuDTO);
            return Result.ok(sysMenuParentListByParameter);
        } catch (Exception e) {
            return Result.errorsFormat(SysTipEnum.MENU_PAGE_QUERY_ERR, e.getMessage());
        }
    }

    /**
     * 查询功能菜单树接口
     *
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public Result querySysMenuTreeListByParameter(QueryMenuDTO queryMenuDTO) {
        try {
            List<SysMenuTreeVO> sysMenuTreeVOList = serviceBySysMenuService.querySysMenuTreeListByParameter(queryMenuDTO);
            return Result.ok(sysMenuTreeVOList);
        } catch (Exception e) {
            return Result.errorsFormat(SysTipEnum.MENU_TREE_QUERY_ERR, e.getMessage());
        }
    }

    /**
     * 功能菜单添加
     *
     * @param sysMenuAddRO - 功能菜单添加对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public Result addMenu(SysMenuAddRO sysMenuAddRO) {
//        1.校验功能菜单名重复
        SysMenu sysMenu = serviceBySysMenuService.queryMenuByName(sysMenuAddRO.getName());
        Result<SysMenuVO> result = menuAddVerification(sysMenu);
        if (!result.isSuccess()) {
            return result;
        }
//        2.父级ID存在校验
        Long parentId = sysMenuAddRO.getParentId();
        if (parentId != null && parentId != 0) {
            SysMenu sysMenuParent = serviceBySysMenuService.getById(parentId);
            result = menuAddVerificationForParent(sysMenuParent);
            if (!result.isSuccess()) {
                return result;
            }
        }
//        3.添加功能菜单
        sysMenu = SysMenuConverter.INSTANCE.addRo2domain(sysMenuAddRO);
        if (serviceBySysMenuService.save(sysMenu)) {
            result.setResult(SysMenuConverter.INSTANCE.domain2vo(sysMenu));
            return result.success();
        }
//        添加失败
        return result.errorFormat(SysTipEnum.MENU_ADD_ERR, sysMenuAddRO.getName());
    }

    /**
     * 功能菜单删除
     *
     * @param menuIdentification - 功能菜单标识
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public Result deleteMenu(final Long menuIdentification) {
//        1.删除功能菜单校验
        SysMenu sysMenu = serviceBySysMenuService.getById(menuIdentification);
        Result result = menuDeleteVerification(sysMenu);
        if (!result.isSuccess()) {
            return result;
        }
//        2.删除功能菜单
        boolean delete = serviceBySysMenuService.deleteMenuById(menuIdentification);
        if (!delete) {
//            删除失败
            return result.errorFormat(SysTipEnum.MENU_DELETE_ERR, sysMenu.getName());
        }
        return Result.ok();
    }

    /**
     * 功能菜单删除
     *
     * @param menuIdentification - 功能菜单标识
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public Result queryMenuById(final Long menuIdentification) {
        SysMenu sysMenu = serviceBySysMenuService.getById(menuIdentification);
        if (ConvertUtils.isEmpty(sysMenu)) {
//            1.根据功能菜单信息查询，该功能菜单不存在
            return Result.errorsFormat(SysTipEnum.MENU_TREE_QUERY_ERR);
        }
        return Result.ok(SysMenuConverter.INSTANCE.domain2vo(sysMenu));
    }

    /**
     * 功能菜单更新
     *
     * @param sysMenuUpdateRO - 功能菜单更新对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public Result updateMenu(SysMenuUpdateRO sysMenuUpdateRO) {
//        1.更新菜单校验
        SysMenu sysMenu = serviceBySysMenuService.getById(sysMenuUpdateRO.getId());
        Result result = menuUpdateVerification(sysMenu);
        if (!result.isSuccess()) {
            return result;
        }
//        2.功能菜单名重复校验
        if (!sysMenu.getName().equals(sysMenuUpdateRO.getName())) {
            SysMenu menu = serviceBySysMenuService.queryMenuByName(sysMenuUpdateRO.getName());
            if (menu != null) {
                return result.errorFormat(SysTipEnum.MENU_UPDATE_ERR_REPEAT, sysMenuUpdateRO.getName());
            }
        }
//        3.功能菜单更新
        boolean update = serviceBySysMenuService.updateByMenuIdentification(sysMenuUpdateRO);
        if (update) {
            return Result.ok();
        }
        return result.errorFormat(SysTipEnum.MENU_UPDATE_ERR, sysMenuUpdateRO.getName());
    }

    /**
     * 查看角色拥有功能菜单接口
     *
     * @param roleIdentification - 角色标识
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    public Result querySysMenuTreeListByRoleId(final Long roleIdentification) {
        SysRole sysRole = sysRoleService.getById(roleIdentification);
        if (ConvertUtils.isEmpty(sysRole)){
            return Result.errorsFormat(SysTipEnum.MENU_TREE_QUERY_ERR_ROLE_NON);
        }
        List<SysMenuTreeVO> sysMenuTreeListByRoleId = serviceBySysMenuService.querySysMenuTreeListByRoleId(roleIdentification);
        return Result.ok(sysMenuTreeListByRoleId);
    }

}